package com.project.petLossSystem.controller.system;

import com.project.petLossSystem.common.Constants;
import com.project.petLossSystem.common.CustomException;
import com.project.petLossSystem.common.ServiceResultEnum;
import com.project.petLossSystem.po.PetPost;
import com.project.petLossSystem.redis.RedisCache;
import com.project.petLossSystem.service.PetPostService;
import com.project.petLossSystem.util.PageQueryUtil;
import com.project.petLossSystem.util.RestTemplateUtil;
import com.project.petLossSystem.util.Result;
import com.project.petLossSystem.util.ResultGenerator;
import com.project.petLossSystem.vo.UserVO;
import com.project.petLossSystem.vo.petPost.PetPostDetailVO;
import org.opencv.core.Rect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Controller
public class SystemPetPostController {
    @Autowired
    private PetPostService petPostService;

    @Autowired
    private RedisCache redisCache;

    @GetMapping("/post/createPost")
    public String createPost() {
        return "/pc/system/create_post";
    }

    @PostMapping("/post/createPost")
    @ResponseBody
    public Result createPost(@RequestParam("postTitle") String postTitle,
                             @RequestParam("petCategoryId") Long petCategoryId,
                             @RequestParam("postType") Byte postType,
                             @RequestParam("addressCategoryId") Integer addressCategoryId,
                             @RequestParam("textContent") String textContent,
                             @RequestParam("Images") MultipartFile[] files,
                             HttpSession session) {
        // 判断参数
        if (!StringUtils.hasText(postTitle) || ObjectUtils.isEmpty(petCategoryId) || ObjectUtils.isEmpty(postType)
                || ObjectUtils.isEmpty(addressCategoryId)) {
            return ResultGenerator.failureResult("参数异常！");
        }
        if (files.length > 3) return ResultGenerator.failureResult("最多上传三张图片！");
        File[] imageFiles = new File[files.length];
        Long userId = ((UserVO) session.getAttribute("user")).getUserId();
        if (!createImageFiles(imageFiles, files, userId)) {
            return ResultGenerator.failureResult("上传失败！");
        }
        String mainImageUrl = "";
        StringBuilder otherImageUrls = new StringBuilder();
        for (int i = 0; i < imageFiles.length; i++) {
            String path = imageFiles[i].getAbsolutePath();
            String imageUrl = path.substring(path.indexOf(Constants.POST_LOCAL_DIC)); // 需要换本地路径
            imageUrl = imageUrl.replaceAll("\\\\", "/"); // 得把反斜杠转正斜杠
            if (i == 0) {
                mainImageUrl = imageUrl;
            } else {
                otherImageUrls.append(imageUrl);
                if (i != imageFiles.length - 1) {
                    otherImageUrls.append(" ");
                }
            }
        }
        // post
        PetPost petPost = new PetPost();
        petPost.setUserId(userId);
        petPost.setPostTitle(postTitle);
        petPost.setPetCategoryId(petCategoryId);
        petPost.setPostType(postType);
        petPost.setAddressCategoryId(addressCategoryId);
        petPost.setTextContent(textContent);
        petPost.setMainImageUrl(mainImageUrl);
        petPost.setOtherImageUrls(otherImageUrls.toString());
        // service
        String result = petPostService.insertPost(petPost, imageFiles[0].getAbsolutePath());
        if (result.equals(ServiceResultEnum.SUCCESS.getResult())) {
            return ResultGenerator.successResult(petPost.getPostId());
        } else {
            // 删除文件
            for (File file : imageFiles) {
                if (file != null) file.delete();
            }
            return ResultGenerator.failureResult(result);
        }
    }

    public boolean createImageFiles(File[] imageFiles, MultipartFile[] files, Long userId) {
        try {
            // 判断是否是图片类型
            for (MultipartFile file : files) {
                if (ImageIO.read(file.getInputStream()) == null) {
                    return false;
                }
            }
            // 用户文件夹
            File directory = new File(Constants.File_IMAGE_UPLOAD_DIC + Constants.POST_URL + userId);
            if (!directory.exists()) {
                directory.mkdirs(); // 不存在则新建
            }
            // 文件通用日期格式名（保证图片的时间一致）
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.DATE_FORMAT_FILE_NAME);
            for (int i = 0; i < imageFiles.length; i++) {
                // 获取文件后缀名
                String suffixName = files[i].getOriginalFilename().substring(files[i].getOriginalFilename().lastIndexOf("."));
                StringBuilder newFileName = new StringBuilder();
                newFileName.append(simpleDateFormat.format(new Date()))
                        .append("_")
                        .append(new Random().nextInt(100));
                if (i == 0) {
                    newFileName.append("_").append("main");
                }
                newFileName.append(suffixName);
                // 创建文件
                imageFiles[i] = new File(directory.getAbsolutePath() + "/" + newFileName.toString());
                // 复制并输出内容到新文件
                files[i].transferTo(imageFiles[i]);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 删除文件
            for (File file : imageFiles) {
                if (file != null) file.delete();
            }
            return false;
        }
        return true;
    }

    @GetMapping("/post/detail/{postId}")
    public String postDetail(@PathVariable("postId") Long postId, Model model) {
        if (ObjectUtils.isEmpty(postId)) {
            CustomException.failure("参数异常！");
        }
        PetPostDetailVO petPostDetailVO = petPostService.getPostDetail(postId);
        if (ObjectUtils.isEmpty(petPostDetailVO)) {
            CustomException.failure("数据异常！");
        } else {
            // 增加浏览量到redis
            redisCache.hashIncrement(Constants.HASH_KEY_FOR_VIEWS, String.valueOf(postId));
            model.addAttribute("petPostDetailVO", petPostDetailVO);
        }
        return "/pc/system/post_detail";
    }

    @GetMapping("/search")
    public String search(@RequestParam Map<String, Object> params, Model model) {
        // 封装分页参数
        if (ObjectUtils.isEmpty(params.get("page"))) {
            params.put("page", 1);
        }
        params.put("rows", Constants.SEARCH_POST_COUNT);
        // 封装排序参数
        if (!ObjectUtils.isEmpty(params.get("sort"))) {
            params.put("sort", String.valueOf(params.get("sort")));
            model.addAttribute("sort", params.get("sort"));
        }
        // 封装筛选参数-帖子分类
        if (!ObjectUtils.isEmpty(params.get("postType"))) {
            Byte postType = Byte.valueOf(String.valueOf(params.get("postType")));
            model.addAttribute("postType", postType);
        }
        // 封装筛选参数-宠物分类
        if (!ObjectUtils.isEmpty(params.get("petCategoryId"))) {
            Long petCategoryId = Long.valueOf(String.valueOf(params.get("petCategoryId")));
            model.addAttribute("petCategoryId", petCategoryId);
        }
        // 封装筛选参数-地址分类
        if (!ObjectUtils.isEmpty(params.get("addressCategoryId"))) {
            Integer addressCategoryId = Integer.valueOf(String.valueOf(params.get("addressCategoryId")));
            model.addAttribute("addressCategoryId", addressCategoryId);
        }
        // 关键字处理
        if (!ObjectUtils.isEmpty(params.get("keyword"))) {
            String keyword = String.valueOf(params.get("keyword"));
            params.put("keyword", keyword.trim());
            model.addAttribute("keyword", params.get("keyword"));
        }
        // service
        PageQueryUtil pageQueryUtil = new PageQueryUtil(params);
        model.addAttribute("pageResult", petPostService.searchPostPage(pageQueryUtil));
        return "/pc/system/search";
    }

    @GetMapping("/searchImg")
    public String searchImg(@RequestParam Map<String, Object> params, HttpSession session, Model model) {
        if(ObjectUtils.isEmpty(params.get("image"))){
            CustomException.failure("上传的匹配图片不存在！");
        }
        // 封装分页参数
        if (ObjectUtils.isEmpty(params.get("page"))) {
            params.put("page", 1);
        }
        params.put("rows", Constants.SEARCH_POST_COUNT);
        // 封装排序参数
        if (!ObjectUtils.isEmpty(params.get("sort"))) {
            params.put("sort", String.valueOf(params.get("sort")));
            model.addAttribute("sort", params.get("sort"));
        }
        // 只从redis拿数据
        Long userId = ((UserVO) session.getAttribute("user")).getUserId();
        List<String> postIds = redisCache.listGet(Constants.LIST_KEY_FOR_MATCH + userId);
        if (!CollectionUtils.isEmpty(postIds)) {
            // service
            PageQueryUtil pageQueryUtil = new PageQueryUtil(params);
            model.addAttribute("pageResult", petPostService.matchPostPage(pageQueryUtil, postIds));
        }
        model.addAttribute("image", params.get("image")); // 图片还是得给人看的
        return "/pc/system/search_img";
    }

    @PostMapping("/searchImg/match")
    @ResponseBody
    public Result match(@RequestParam("petCategoryId") Long petCategoryId,
                        @RequestParam("postType") Byte postType,
                        @RequestParam("addressCategoryId") Integer addressCategoryId,
                        @RequestParam("Image") MultipartFile file,
                        HttpSession session) {
        // 判断参数
        if (ObjectUtils.isEmpty(petCategoryId) || ObjectUtils.isEmpty(postType)
                || ObjectUtils.isEmpty(addressCategoryId)) {
            return ResultGenerator.failureResult("参数异常！");
        }
        Long userId = ((UserVO) session.getAttribute("user")).getUserId();
        File image = null;
        try {
            // 判断是否是图片类型
            if (ImageIO.read(file.getInputStream()) == null) {
                return ResultGenerator.failureResult("请上传图片！");
            }
            // 文件通用日期格式名
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constants.DATE_FORMAT_FILE_NAME);
            // 获取文件后缀名
            String suffixName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
            StringBuilder newFileName = new StringBuilder();
            newFileName.append(simpleDateFormat.format(new Date()))
                    .append("_")
                    .append(new Random().nextInt(100))
                    .append(suffixName);
            // 创建文件
            image = new File(Constants.File_IMAGE_UPLOAD_DIC + Constants.MATCH_LOCAL_DIC + newFileName.toString());
            // 复制并输出内容到新文件
            file.transferTo(image);
            String result = petPostService.getPostIdsForMatch(image.getAbsolutePath(), petCategoryId, postType, addressCategoryId, userId);
            if (result.equals(ServiceResultEnum.SUCCESS.getResult())) {
                // 返回图片url
                return ResultGenerator.successResult(Constants.MATCH_URL + newFileName.toString());
            } else {
                // 删除文件
                if (image != null) image.delete();
                return ResultGenerator.failureResult(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 删除文件
            if (image != null) image.delete();
        }
        return ResultGenerator.failureResult("系统错误！");
    }

    @PutMapping("/post/delete")
    @ResponseBody
    public Result delete(@RequestParam("postId") Long postId, HttpSession session){
        String result = petPostService.deleteOwnPost(postId, session);
        if(result.equals(ServiceResultEnum.SUCCESS.getResult())){
            return ResultGenerator.successResult();
        }else return ResultGenerator.failureResult(result);
    }

}
